package com.site.common.annotation;

import com.site.common.annotation.enums.AccessLimitStoreType;
import com.site.common.annotation.enums.AccessLimitResourceType;
import com.site.common.annotation.enums.AccessLimitType;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

/**
 * 限流注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AccessLimit {

    /**
     * 限流类型：LIMIT：限流 ,COUNT：访问次数，默认限流资源，不限制次数
     */
    AccessLimitType type() default AccessLimitType.LIMIT;

    /**
     * 类型 GUAVA:内存  REDIS：redis缓存
     */
    AccessLimitStoreType store() default AccessLimitStoreType.GUAVA;

    /**
     * 访问限流类型：IP , 自定义CUSTOMER,
     */
    AccessLimitResourceType resourceType() default AccessLimitResourceType.IP;
    // CUSTOMER 自定义类型时，key 自定义指定 @AccessLimit(key="test")
    String key() default "";
    // key 分隔符
    String separator() default ":";

    /**
     * 获取令牌的等待时间  默认0
     */
    int timeOut() default 0;

    /**
     * 超时时间单位，默认毫秒
     */
    TimeUnit timeOutUnit() default TimeUnit.MILLISECONDS;

    // ----------------------------- guava RateLimiter newConcurrentMap ----------------------------
    // 用法：@AccessLimit(number=2)
    /**
     * 每秒向桶中放入令牌的数量   默认最大即不做限流
     */
    double number() default Double.MAX_VALUE;

    // ----------------------------- redis ----------------------------
    // 用法：@AccessLimit(count = 5,store = AccessLimitStoreType.REDISTYPE)
    /**
     * 前缀
     */
    String prefix() default "ACCESS:LIMIT:";

    /**
     * 访问次数
     */
    int count() default 0;
}